Trong các hệ thống website đang hoạt động trên Internet, một tính năng không thể thiếu là xác thực người dùng. Tính năng này giúp các website biết được ai đang sử dụng hệ thống để điều hướng thành viên đến các nguồn tài nguyên khác nhau, ngoài ra nó bảo mật thông tin khác nhau với các nhóm thành viên khác nhau. Trước đây, để viết một tính năng xác thực người dùng là mất rất nhiều công sức, nhưng Laravel đã làm mọi việc trở nên thật đơn giản.
Các thiết lập cấu hình trong Laravel Authentication
Laravel đã tạo sẵn các Controller, View, Middleware, Model… và cả file cấu hình config/auth.php để chúng ta chỉ cần thiết lập là có thể chạy được ngay.
Config/auth.php thiết lập cấu hình Laravel Authentication
Đầu tiên, chúng ta sẽ đi vào file thiết lập cấu hình config/auth.php để xem có những gì cần cài đặt khi chạy Laravel Authentication:
'guards' => [
'web' => [
'driver' => 'session',
'provider' => 'users',
],
'api' => [
'driver' => 'token',
'provider' => 'users',
],
],
'providers' => [
'users' => [
'driver' => 'eloquent',
'model' => App\User::class,
],
// 'users' => [
// 'driver' => 'database',
// 'table' => 'users',
// ],
],
Trong file này có hai phần cần quan tâm là guards và providers, guards định nghĩa cách thức xác thực người dùng cho các request, mặc định guards sử dụng Laravel Session để lưu trữ các thông tin trạng thái. Providers định nghĩa các cách thức lưu trữ và lấy dữ liệu để xác thực người dùng. Laravel hỗ trợ hai cách thức là Laravel Eloquent ORM hoặc Laravel Query Builder để tương tác với CSDL trong xác thực, ngoài ra nó cũng cho phép định nghĩa riêng các providers của chính bạn để sử dụng, tuy nhiên chúng ta có lựa chọn các cách thức mặc định này là đã đáp ứng rất tốt cho ứng dụng web.
Các Model, View, Controller tạo sẵn cho Laravel Authentication
Tiếp theo, chúng ta sẽ xem xét các thành phần được tạo ra sẵn trong Laravel để phục vụ cho việc xác thực. Mặc định một Eloquent Model app\User.php được tạo ra, model này được sử dụng mặc định trong file cấu hình config/auth.php. Có một số chú ý khi tạo bảng users tương ứng trong CSDL: cột password phải có độ dài ít nhất là 60 ký tự, phải có cột remember_token với độ dài 100 ký tự và có thể null, cột này sử dụng cho tùy chọn nhớ xác thực trong form xác thực. Laravel cũng tạo ra một loạt các Controller trong app\Http\Controllers\Auth như:
- RegisterController: Quản lý việc đăng ký thành viên mới.
- LoginController: Quản lý việc đăng nhập các thành viên.
- ForgotPasswordController: gửi email với đường link sử dụng cho reset password.
- ResetPasswordController: kiểm soát việc reset mật khẩu với các logic do lập trình viên thêm vào.
Với phần lớn các ứng dụng web, các Controller ở trên không cần thay đổi gì. Các view sử dụng trong Laravel Authentication cũng được tạo ra sẵn nằm trong thư mục resources/views/auth.
Tạo ứng dụng web có xác thực bằng Laravel Authentication
k, chúng ta đã dông dài một chút, giờ chúng ta sẽ bắt tay thêm tính năng xác thực người dùng vào ứng dụng web có sẵn trong các bài viết trước trong allaravel.com hoặc bạn xem lại Cách cài đặt môi trường test cho Laravel.
Cài đặt thiết lập Laravel Authentication
Đầu tiên, chúng ta sử dụng lệnh artisan sau để tạo ra các thành phần, các cấu hình mặc định sử dụng trong Laravel authentication.
c:\xampp\htdocs\laravel-test>php artisan make:auth
Authentication scaffolding generated successfully.
Câu lệnh trên cũng thêm một số route vào routes/web.php. Tiếp theo đó chúng ta sử dụng Laravel Migrate để tạo các bảng liên quan trong CSDL. Chú ý: do trong bài Làm việc với CSDL trong Laravelchúng ta có một ví dụ đơn giản về cách xác thực và làm việc với CSDL, ví dụ đã tạo ra bảng users trong database do đó nếu chúng ta chạy lệnh artisan migrate nó sẽ báo lỗi rằng bảng users đã tồn tại.
c:\xampp\htdocs\laravel-test>php artisan migrate
Migration table created successfully.
[Illuminate\Database\QueryException]
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'users' alre
ady exists (SQL: create table `users` (`id` int unsigned not null auto_incr
ement primary key, `name` varchar(255) not null, `email` varchar(255) not n
ull, `password` varchar(255) not null, `remember_token` varchar(100) null,
`created_at` timestamp null, `updated_at` timestamp null) default character
set utf8mb4 collate utf8mb4_unicode_ci)
[PDOException]
SQLSTATE[42S01]: Base table or view already exists: 1050 Table 'users' already exists
Chúng ta có thể xóa bảng users này đi để chạy lại lệnh artisan hoặc chúng ta thêm các yêu cầu trên các cột như ở phần đầu bài viết, thêm cột remember_token. Ở đây, tôi thực hiện xóa bảng users đã có và chạy lại lệnh php artisan migrate.
c:\xampp\htdocs\laravel-test>php artisan migrate
Migration table created successfully.
[Illuminate\Database\QueryException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was t
oo long; max key length is 767 bytes (SQL: alter table `users` add unique `
users_email_unique`(`email`))
[PDOException]
SQLSTATE[42000]: Syntax error or access violation: 1071 Specified key was t
oo long; max key length is 767 bytes
Oạch, vẫn lỗi nhưng lần này lỗi khác liên quan đến độ dài tối đa của key. Sau một hồi tìm hiểu, lỗi này là do Laravel 5.4 đã thay đổi character set mặc định sang utf8mb4 để hỗ trợ việc lưu trữ emojis (một đoạn ký tự sắp xếp thành hình biểu cảm, ví dụ (^o^) (^_-) ┐(´~`)┌). Lỗi này sẽ xảy ra khi bạn sử dụng mySQL phiên bản 5.7.7 trở xuống. Để sửa lỗi này, bạn sửa lại file AppServiceProvider.php nằm trong thư mục app\Providers
<?php
namespace App\Providers;
use Illuminate\Support\ServiceProvider;
use Schema;
class AppServiceProvider extends ServiceProvider
{
/**
* Bootstrap any application services.
*
* @return void
*/
public function boot()
{
Schema::defaultStringLength(191);
}
/**
* Register any application services.
*
* @return void
*/
public function register()
{
//
}
}
Ok, giờ chạy lại php artisan migrate và mọi chuyện đã rất ổn.
c:\xampp\htdocs\laravel-test>php artisan migrate
Migrated: 2014_10_12_000000_create_users_table
Migrated: 2014_10_12_100000_create_password_resets_table
Quá trình migrate trên tạo ra hai bảng là users và password_reset trong CSDL laravel-test. Như vậy, ứng dụng của chúng ta đã cài đặt xong tính năng xác thực người dùng. Chúng ta sẽ kiểm tra xem nó hoạt động như thế nào, do trong users hiện chưa có bản ghi nào, nên chưa có user nào đăng nhập được, bạn cần đăng ký một tài khoản trước đã. Vào http://laravel.dev/register
Có rất nhiều route được tạo ra khi bạn chạy Laravel Authentication, để biết được các route nào được thêm vào sử dụng lệnh
// Sử dụng cho phiên bản Laravel 4 trở xuống
php artisan routes
// Sử dụng cho Laravel 5
php artisan route:list
Chúng ta sẽ thấy một số đường dẫn cơ bản như sau:
- http://laravel.dev/login: sử dụng cho đăng nhập
- http://laravel.dev/logout: sử dụng để đăng xuất
- http://laravel.dev/register: sử dụng để đăng ký thành viên.
- http://laravel.dev/password/email: gửi email reset mật khẩu.
- http://laravel.dev/password/reset/{token}: đường link gửi trong email reset mật khẩu.
- http://laravel.dev/password/reset: form reset mật khẩu.
Ok, giờ tạm nghỉ 10 phút cho bạn khám phá tính năng Laravel Authentication. Đầu tiên, đăng ký một tài khoản, sau đó thực hiện đăng nhập, đăng xuất… Bạn thấy đấy, việc cài đặt sử dụng Laravel authentication thật đơn giản phải không. Tiếp theo chúng ta sẽ đi sâu hơn chút các công việc như: chỉnh sửa lại các giao diện mặc định, thiết lập xác thực cho các đường dẫn cần xác thực.
Chỉnh sửa giao diện mặc định trong Laravel Authentication
Chúng ta cần sửa lại giao diện mặc định trong xác thực người dùng để phù hợp với giao diện chung toàn bộ website. Tất cả các view mặc định của Laravel Authentication đều nằm trong resources/views/auth. Đầu tiên chúng ta sẽ điều chỉnh trang đăng nhập login.blade.php trong thư mục trên.
@extends('layouts.default')
@section('title', 'Đăng nhập - Allaravel.com')
@section('content')
<div class="row">
<div class="col-md-8 col-md-offset-2">
<div class="panel panel-default">
<div class="panel-heading">Đăng nhập</div>
<div class="panel-body">
<form class="form-horizontal" role="form" method="POST" action="{{ route('login') }}">
{{ csrf_field() }}
<div class="form-group{{ $errors->has('email') ? ' has-error' : '' }}">
<label for="email" class="col-md-4 control-label">Địa chỉ email</label>
<div class="col-md-6">
<input id="email" type="email" class="form-control" name="email" value="{{ old('email') }}" required autofocus>
@if ($errors->has('email'))
<span class="help-block">
<strong>{{ $errors->first('email') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group{{ $errors->has('password') ? ' has-error' : '' }}">
<label for="password" class="col-md-4 control-label">Mật khẩu</label>
<div class="col-md-6">
<input id="password" type="password" class="form-control" name="password" required>
@if ($errors->has('password'))
<span class="help-block">
<strong>{{ $errors->first('password') }}</strong>
</span>
@endif
</div>
</div>
<div class="form-group">
<div class="col-md-6 col-md-offset-4">
<div class="checkbox">
<label>
<input type="checkbox" name="remember" {{ old('remember') ? 'checked' : '' }}> Ghi nhớ mật khẩu
</label>
</div>
</div>
</div>
<div class="form-group">
<div class="col-md-8 col-md-offset-4">
<button type="submit" class="btn btn-primary">
Đăng nhập
</button>
<a class="btn btn-link" href="{{ route('password.request') }}">
Quên mật khẩu?
</a>
</div>
</div>
</form>
</div>
</div>
</div>
</div>
@endsection
Chúng ta đưa blade template mặc định vào cho trang login @extends(‘layouts.default’), xem lại Laravel Blade xây dựng giao diện module hóa. Giờ chúng ta vào thử http://laravel.dev/login xem giao diện như thế nào.
Hehe, nhìn khá hơn đấy chứ. Với các view còn lại bạn tự thực hành nhé, code của toàn bộ các view đã thay đổi tôi sẽ đưa vào cuối bài, bạn có thể tải về để thực hành.
Thiết lập xác thực cho các URL yêu cầu xác thực
Chúng ta đã đi qua được quá nửa chặng đường, tiếp theo chúng ta xem cách thức thiết lập xác thực cho các đường dẫn yêu cầu. Quay lại với ví dụ quản lý sản phẩm trong Xây dựng truy vấn bằng Laravel Query Builder, phần này cho phép tạo mới, chỉnh sửa, quản lý danh sách các sản phẩm, đây là tính năng dành cho quản trị viên, do đó chúng ta yêu cầu phải xác thực người dùng mới được sử dụng phần quản trị sản phẩm.
Trong ví dụ này, đường dẫn của phần quản trị là http://laravel.dev/product, nên chuyển sang http://laravel.dev/admin/product để quy hoạch lại, tất cả những gì cần quản trị sẽ đưa vào http://laravel.dev/admin. Laravel Authentication đã tạo ra một Middleware là auth (xem thêm Laravel Middleware) dùng để xác thực người dùng, chúng ta chỉ việc sử dụng middleware này trong các route.
Route::resource('admin/product', 'ProductController', [
'only' => ['create', 'store', 'edit'],
'middleware' => 'auth'
]);
bạn có thể xem auth đăng ký như thế nào tại app\Http\Kernel.php trong phần routeMiddleware. Giờ bạn vào lại thử trang quản lý danh sách sản phẩm http://laravel.dev/admin/product nếu chưa đăng nhập nó sẽ tự động chuyển hướng đến trang đăng nhập http://laravel.dev/login. Bạn thực hiện đăng nhập xong sẽ vào lại trang danh sách bình thường.
Lời kết
Laravel Authentication thật sự rất đơn giản, tích hợp nhanh vào các ứng dụng web đòi hỏi phải xác thực. Chúng ta còn rất nhiều điều cần tìm hiểu thêm nữa về xác thực người dùng như sử dụng ajax kết hợp với Laravel Authentication để xác thực, một tính năng cũng được các trang web sử dụng nhiều hiện nay là xác thực người dùng bằng sử dụng các mạng xã hội… Tất cả những vấn đề này chúng ta sẽ quay lại trong các bài viết tiếp theo, các bạn đón xem nhé.